<template>
  <div class="plantuml-editor">
    <!-- 工具栏 -->
    <el-card class="toolbar-card" shadow="never">
      <div class="toolbar">
        <h3>UML 可视化构建</h3>
        <div class="toolbar-actions">
          <el-select v-model="currentDiagramType" @change="onDiagramTypeChange" placeholder="选择图表类型"
            style="width: 120px">
            <el-option key="class" label="类图" value="class" />
            <el-option key="activity" label="活动图" value="activity" />
            <el-option key="sequence" label="时序图" value="sequence" />
            <el-option key="usecase" label="用例图" value="usecase" />
            <el-option key="state" label="状态图" value="state" />
          </el-select>

          <el-input v-model="diagramTitle" placeholder="图表标题（可为空）" style="width: 200px" />

          <el-select v-model="currentRelationshipType" placeholder="关系类型" style="width: 120px">
            <el-option v-for="type in getRelationshipTypes()" :key="type.value" :label="type.label"
              :value="type.value" />
          </el-select>

          <el-button type="primary" @click="showTemplateModal = true" :icon="Document">
            选择模板
          </el-button>
          <el-button @click="clearAll" :icon="Delete">清空</el-button>
          <el-button @click="exportCode" :icon="Download">导出代码</el-button>
          <el-button type="success" @click="saveDiagram" :icon="Check">保存</el-button>
        </div>
      </div>
    </el-card>

    <!-- 模板选择对话框 -->
    <el-dialog v-model="showTemplateModal" title="选择模板" width="80%" :before-close="() => showTemplateModal = false">
      <div class="template-grid">
        <el-card v-for="template in getTemplates()" :key="template.id" class="template-item" shadow="hover"
          @click="loadTemplate(template)">
          <div class="template-preview">
            <img :src="template.preview" :alt="template.name" />
          </div>
          <div class="template-info">
            <h4>{{ template.name }}</h4>
            <p>{{ template.description }}</p>
          </div>
        </el-card>
      </div>
    </el-dialog>

    <!-- 模型选择对话框 -->
    <el-dialog v-if="useModel" v-model="showModelSelectionModal" title="选择模型" width="600px"
      :before-close="() => showModelSelectionModal = false">
      <div class="model-selection">
        <div class="model-info">
          <p>请为 <strong>{{ pendingElementData?.label || pendingElementData?.type }}</strong> 选择一个模型：</p>
        </div>
        <div class="model-grid">
          <el-card v-for="model in getAvailableModels(pendingElementData?.type)" :key="model.id" class="model-item"
            shadow="hover" :class="{ selected: selectedModel === model.id }" @click="selectedModel = model.id">
            <div class="model-header">
              <h4>{{ model.name }}</h4>
            </div>
            <div class="model-description">
              <p>{{ model.description }}</p>
            </div>
          </el-card>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showModelSelectionModal = false">取消</el-button>
          <el-button type="primary" @click="confirmModelSelection" :disabled="!selectedModel">
            确认选择
          </el-button>
        </div>
      </template>
    </el-dialog>

    <div class="main-container">
      <!-- 左侧元素库 -->
      <el-card class="element-library" shadow="never">
        <template #header>
          <div class="library-header">
            <span>元素库</span>
            <small>拖拽元素到画布</small>
          </div>
        </template>

        <div class="library-content">
          <el-collapse v-model="activeLibrarySections">
            <el-collapse-item title="基本元素" name="basic">
              <div class="library-elements">
                <el-card v-for="(element, index) in getLibraryElements()" :key="element.type + '_' + (element.activityType || element.participantType || element.usecaseType || element.stateType || index)" class="library-element"
                  shadow="hover" draggable="true" @dragstart="onDragStart($event, element)" @dragend="onDragEnd">
                  <div class="element-icon">{{ getElementIcon(element.type) }}</div>
                  <div class="element-label">{{ element.label }}</div>
                </el-card>
              </div>
            </el-collapse-item>
          </el-collapse>
        </div>
      </el-card>

      <!-- 中间画布区域 -->
      <el-card class="canvas-container" shadow="never">
        <template #header>
          <div class="canvas-header">
            <span>画布</span>
            <div class="canvas-controls">
              <el-button size="small" @click="exportCanvas" :icon="Download">导出</el-button>
              <el-button size="small" @click="importCanvas" :icon="Upload">导入</el-button>
              <el-button size="small" @click="zoomIn" :icon="ZoomIn">放大</el-button>
              <el-button size="small" @click="zoomOut" :icon="ZoomOut">缩小</el-button>
              <el-button size="small" @click="resetView" :icon="Refresh">重置视图</el-button>
              <el-button size="small" @click="autoLayout" :icon="Grid">自动布局</el-button>
              <el-button size="small" @click="generateRelationships" :icon="Connection">自动生成关系</el-button>
              <el-button v-if="currentDiagramType === 'activity'" size="small" type="success" @click="openExecutionDialog"
                :icon="VideoPlay">执行</el-button>
              <el-button v-if="currentDiagramType === 'activity' && !isExecuting && executionPath.length > 0" size="small"
                @click="replayExecution" :icon="VideoPlay">重播</el-button>
              <el-switch v-if="currentDiagramType === 'activity'" v-model="loopExecution" active-text="循环"
                style="margin-left:8px" />
            </div>
          </div>
        </template>

        <div class="canvas-wrapper">
          <canvas ref="canvas" class="canvas" @dragover="onDragOver" @drop="onDrop" @mousemove="onCanvasMouseMove"
            @mouseup="onCanvasMouseUp" @mousedown="onCanvasMouseDown" @wheel="onCanvasWheel" @mouseleave="onCanvasMouseLeave"></canvas>
        </div>
      </el-card>
      <!-- 执行参数对话框（仅活动图） -->
      <el-dialog v-model="showExecutionDialog" title="执行流程" width="500px"
        :before-close="() => showExecutionDialog = false">
        <el-form label-position="top" size="small">
          <el-form-item label="开始节点">
            <el-select v-model="executionParams.startId" placeholder="选择start节点">
              <el-option v-for="node in activityStartNodes" :key="node.id" :label="node.name || 'start'"
                :value="node.id" />
            </el-select>
          </el-form-item>
          <el-form-item label="分支选择（若流程包含分支）">
            <el-input v-model="executionParams.branchChoices" placeholder="用逗号分隔，例如: yes,no,yes" />
            <div class="form-tip">
              <small>支持的分支值：yes/no, true/false, 成功/失败, 通过/不通过。如果关系没有名称，第一个分支默认为yes，第二个为no。</small>
            </div>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="showExecutionDialog = false">取消</el-button>
            <el-button type="success" @click="startExecution">开始执行</el-button>
          </div>
        </template>
      </el-dialog>

      <!-- 保存对话框 -->
      <el-dialog v-model="showSaveDialog" title="保存图表" width="500px" :before-close="() => showSaveDialog = false">
        <el-form label-position="top" size="small">
          <el-form-item label="图表标题">
            <el-input v-model="saveForm.title" placeholder="请输入图表标题" />
          </el-form-item>
          <el-form-item label="描述">
            <el-input v-model="saveForm.description" type="textarea" placeholder="请输入图表描述（可选）" />
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="showSaveDialog = false">取消</el-button>
            <el-button type="success" @click="confirmSave">确认保存</el-button>
          </div>
        </template>
      </el-dialog>

      <!-- 右侧属性面板和实时预览 -->
      <div class="right-panel">
        <!-- 属性面板 -->
        <el-card class="property-panel" shadow="never">
          <template #header>
            <span>属性编辑</span>
          </template>

          <div v-if="selectedElement" class="panel-content">
            <el-form label-position="top" size="small">
              <el-form-item label="名称">
                <el-input v-model="selectedElement.name" @input="updateElement" />
              </el-form-item>

              <!-- 模型选择（仅对非关系元素显示，且需要启用模型功能） -->
              <template v-if="useModel && selectedElement && selectedElement.type && selectedElement.type !== 'relationship'">
                <el-form-item label="模型">
                  <el-select v-model="selectedElement.modelId" @change="updateElementModel" placeholder="选择模型">
                    <el-option
                      v-for="model in getAvailableModels(selectedElement && selectedElement.type ? selectedElement.type : '')"
                      :key="model.id" :label="model.name" :value="model.id" />
                  </el-select>
                  <div v-if="selectedElement.modelName" class="model-info">
                    <small>{{ selectedElement.modelName }}</small>
                  </div>
                </el-form-item>
              </template>

              <!-- 类图特定属性 -->
              <template
                v-if="currentDiagramType === 'class' && selectedElement && selectedElement.type && (selectedElement.type === 'class' || selectedElement.type === 'interface')">
                <el-form-item label="属性">
                  <div class="attributes-list">
                    <div v-for="(attr, index) in (selectedElement.attributes || [])" :key="index"
                      class="attribute-item">
                      <el-select v-model="attr.visibility" @change="updateElement" style="width: 80px">
                        <el-option label="+" value="public" />
                        <el-option label="-" value="private" />
                        <el-option label="#" value="protected" />
                      </el-select>
                      <el-input v-model="attr.name" @input="updateElement" placeholder="属性名" />
                      <el-input v-model="attr.type" @input="updateElement" placeholder="类型" />
                      <el-button @click="removeAttribute(index)" type="danger" size="small" :icon="Close" />
                    </div>
                    <el-button @click="addAttribute" type="primary" size="small" :icon="Plus">添加属性</el-button>
                  </div>
                </el-form-item>

                <el-form-item label="方法">
                  <div class="methods-list">
                    <div v-for="(method, index) in (selectedElement.methods || [])" :key="index" class="method-item">
                      <el-select v-model="method.visibility" @change="updateElement" style="width: 80px">
                        <el-option label="+" value="public" />
                        <el-option label="-" value="private" />
                        <el-option label="#" value="protected" />
                      </el-select>
                      <el-input v-model="method.name" @input="updateElement" placeholder="方法名" />
                      <el-input v-model="method.returnType" @input="updateElement" placeholder="返回类型" />
                      <el-button @click="removeMethod(index)" type="danger" size="small" :icon="Close" />
                    </div>
                    <el-button @click="addMethod" type="primary" size="small" :icon="Plus">添加方法</el-button>
                  </div>
                </el-form-item>
              </template>

              <!-- 关系属性 -->
              <template v-if="selectedElement && selectedElement.type && selectedElement.type === 'relationship'">
                <el-form-item label="关系类型">
                  <el-select v-model="selectedElement.relationshipType" @change="updateElement">
                    <el-option v-for="type in getRelationshipTypes()" :key="type.value" :label="type.label"
                      :value="type.value" />
                  </el-select>
                </el-form-item>
              </template>

              <!-- 删除按钮 -->
              <el-form-item>
                <el-button type="danger" @click="deleteSelectedElement" :icon="Delete" style="width: 100%">
                  删除{{ selectedElement && selectedElement.type && selectedElement.type === 'relationship' ? '关系' : '元素'
                  }}
                </el-button>
              </el-form-item>
            </el-form>
          </div>

          <div v-else class="empty-panel">
            <el-empty description="请长按鼠标左键选择一个元素进行编辑" :image-size="80">
              <template #description>
                <div class="empty-description">
                  <p>请长按鼠标左键选择一个元素进行编辑</p>
                  <p class="empty-tip">提示：长按元素 0.5 秒即可选中</p>
                </div>
              </template>
            </el-empty>
          </div>
        </el-card>

        <!-- 预览面板 -->
        <el-card class="preview-panel" shadow="never">
          <template #header>
            <div class="preview-header">
              <span>实时预览</span>
              <div class="preview-controls">
                <el-button size="small" @click="refreshPreview" :icon="Refresh">刷新</el-button>
                <el-button size="small" @click="downloadImage" :icon="Download">下载</el-button>
              </div>
            </div>
          </template>

          <div class="preview-container">
            <div v-if="loading" class="loading-container">
              <el-icon class="is-loading">
                <Loading />
              </el-icon>
              <p>生成UML图中...</p>
            </div>

            <div v-else-if="error" class="error-container">
              <el-icon>
                <Warning />
              </el-icon>
              <p>{{ error }}</p>
            </div>

            <div v-else-if="!umlImageUrl" class="empty-container">
              <div class="empty-icon-container">
                <el-icon size="40">
                  <Picture />
                </el-icon>
              </div>
              <p>拖拽元素到画布开始构建UML图</p>
            </div>

            <div v-else class="image-container">
              <img :src="umlImageUrl" :alt="'UML Diagram'" class="uml-image" @click="showImagePreview = true" />
            </div>
          </div>
        </el-card>
      </div>
    </div>

    <!-- 右键菜单 -->
    <div v-if="showContextMenuFlag" class="context-menu" :style="contextMenuStyle" @click.stop>
      <div class="context-menu-item" @click="copyElement">
        <el-icon>
          <CopyDocument />
        </el-icon>
        <span>复制</span>
      </div>
      <div class="context-menu-item" @click="deleteSelectedElement">
        <el-icon>
          <Delete />
        </el-icon>
        <span>删除</span>
      </div>
    </div>

    <!-- 图片预览对话框 -->
    <el-dialog v-model="showImagePreview" title="图片预览" width="90%" :before-close="() => showImagePreview = false" center>
      <div class="image-preview-container">
        <img :src="umlImageUrl" :alt="'UML Diagram'" class="preview-image" />
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showImagePreview = false">关闭</el-button>
          <el-button type="primary" @click="downloadImage">下载图片</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 文件输入 -->
    <input ref="fileInput" type="file" accept=".json" style="display: none" @change="handleFileImport" />
  </div>
</template>

<script setup>
import { ref, onMounted, watch, onUnmounted, nextTick, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Document,
  Edit,
  Delete,
  Download,
  VideoPlay,
  Grid,
  Connection,
  Close,
  Plus,
  Refresh,
  Picture,
  CopyDocument,
  ZoomIn,
  ZoomOut,
  Upload,
  Loading,
  Warning,
  Check
} from '@element-plus/icons-vue'
import { generateUMLImage, saveDiagram as apiSaveDiagram, removeImages } from '../api/plantumlService'

import {
  getElementWidth,
  getElementHeight,
  getElementCenter,
  getElementEdgePoint,
  pointToLineDistance,
  getDiagramTypeTitle,
  getRelationshipTypeName,
  getElementIcon,
} from './PlantUMLEditor/utils.js'

import {
  drawRoundedRectangle,
  drawSelectionBox,
  drawConnectionPoints,
  drawGrid,
  drawActivityElement,
  drawLifelineElement,
  drawClassElement,
  drawElementContent,
  drawRelationship,
  drawConnectingLine,
  drawHighlightedRelationship,
  drawElementHighlight,
  drawStateElement,
  drawUseCaseElement
} from './PlantUMLEditor/canvasRenderer.js'

import {
  generatePlantUMLCode
} from './PlantUMLEditor/umlGenerator.js'

import {
  getAllTemplates
} from './PlantUMLEditor/templates.js'

// 定义props
const props = defineProps({
  bizId: {
    type: [String, Number],
    default: '1'
  },
  useModel: {
    type: Boolean,
    default: false
  }
})

// 定义事件
const emit = defineEmits(['save-success'])

const elements = ref([])
const selectedElement = ref(null)
const umlImageUrl = ref('')
const loading = ref(false)
const error = ref('')
const canvasWidth = ref(800)
const canvasHeight = ref(600)
const currentDiagramType = ref('class')
const showTemplateModal = ref(false)
const activeLibrarySections = ref(['basic', 'relationships'])
const diagramTitle = ref('')

// 拖拽相关状态
const isDragging = ref(false)
const dragElement = ref(null)
const dragPosition = ref({ x: 0, y: 0 })

// 元素移动相关状态
const isMovingElement = ref(false)
const movingElement = ref(null)
const moveStartPosition = ref({ x: 0, y: 0 })

// 连接相关状态
const isConnecting = ref(false)
const connectionStart = ref({ x: 0, y: 0, elementId: '' })
const connectionEnd = ref({ x: 0, y: 0 })
const currentRelationshipType = ref('association')

// 右键菜单状态
const showContextMenuFlag = ref(false)
const contextMenuStyle = ref({ left: '0px', top: '0px' })

// 模型选择对话框状态
const showModelSelectionModal = ref(false)
const pendingElementData = ref(null)
const pendingPosition = ref({ x: 0, y: 0 })
const selectedModel = ref('')

// 画布缩放和平移状态（已移至Canvas相关状态部分）

// Canvas相关状态
const canvas = ref(null)
const ctx = ref(null)
const isCanvasInitialized = ref(false)

// Canvas变换状态
const canvasScale = ref(1)
const canvasTranslateX = ref(0)
const canvasTranslateY = ref(0)
const isPanning = ref(false)
const panStartPosition = ref({ x: 0, y: 0 })

// 连接相关状态
const connectingElement = ref(null)
const connectingPoint = ref('')

// 文件输入引用
const fileInput = ref(null)

// 执行相关状态（仅活动图）
const showExecutionDialog = ref(false)
const isExecuting = ref(false)
const executionParams = ref({ startId: '', branchChoices: '' })
const executionPath = ref([]) // 关系ID序列
const executedNodeIds = ref(new Set())
const animation = ref({ running: false, progress: 0, dashOffset: 0, relIndex: 0 })
const loopExecution = ref(false)

// 保存相关状态
const showSaveDialog = ref(false)
const saveForm = ref({
  id: '',
  title: '',
  description: ''
})

// 图片预览状态
const showImagePreview = ref(false)

// 服务器返回的图片路径
const serverImagePath = ref('')

// 模型数据定义
const models = ref({
  class: [
    { id: 'user', name: '用户模型', description: '用户相关的数据模型' },
    { id: 'product', name: '产品模型', description: '产品相关的数据模型' },
    { id: 'order', name: '订单模型', description: '订单相关的数据模型' },
    { id: 'category', name: '分类模型', description: '分类相关的数据模型' },
    { id: 'custom', name: '自定义模型', description: '用户自定义的模型' }
  ],
  interface: [
    { id: 'service', name: '服务接口', description: '服务层接口定义' },
    { id: 'repository', name: '仓储接口', description: '数据访问层接口' },
    { id: 'controller', name: '控制器接口', description: '控制器层接口' },
    { id: 'custom', name: '自定义接口', description: '用户自定义的接口' }
  ],
  activity: [
    { id: 'workflow', name: '工作流', description: '业务流程工作流' },
    { id: 'process', name: '处理流程', description: '数据处理流程' },
    { id: 'custom', name: '自定义活动', description: '用户自定义的活动' },
    { id: 'activity_start', type: 'activity', activityType: 'start', label: '开始' },
    { id: 'activity_end', type: 'activity', activityType: 'end', label: '结束' },
    { id: 'activity_action', type: 'activity', activityType: 'action', label: '动作' },
    { id: 'activity_decision', type: 'activity', activityType: 'decision', label: '决策' },
    { id: 'activity_merge', type: 'activity', activityType: 'merge', label: '合并' },
    { id: 'activity_fork', type: 'activity', activityType: 'fork', label: '分叉' },
    { id: 'activity_join', type: 'activity', activityType: 'join', label: '汇合' },
    { id: 'activity_note', type: 'activity', activityType: 'note', label: '注释' },
    { id: 'activity_partition', type: 'activity', activityType: 'partition', label: '分区' },
    { id: 'activity_repeat', type: 'activity', activityType: 'repeat', label: '循环' },
    { id: 'activity_break', type: 'activity', activityType: 'break', label: '跳出' },
    { id: 'activity_switch', type: 'activity', activityType: 'switch', label: '分支' },
    { id: 'activity_case', type: 'activity', activityType: 'case', label: '分支项' },
    { id: 'activity_endswitch', type: 'activity', activityType: 'endswitch', label: '结束分支' },
    { id: 'activity_condition', type: 'activity', activityType: 'condition', label: '条件判断' },
    { id: 'activity_else', type: 'activity', activityType: 'else', label: '否则' },
    { id: 'activity_endif', type: 'activity', activityType: 'endif', label: '结束判断' },
    { id: 'activity_while', type: 'activity', activityType: 'while', label: '循环判断' },
    { id: 'activity_endwhile', type: 'activity', activityType: 'endwhile', label: '结束循环' }
  ],
  usecase: [
    { id: 'feature', name: '功能用例', description: '系统功能用例' },
    { id: 'business', name: '业务用例', description: '业务流程用例' },
    { id: 'custom', name: '自定义用例', description: '用户自定义的用例' }
  ],
  state: [
    { id: 'lifecycle', name: '生命周期', description: '对象生命周期状态' },
    { id: 'workflow', name: '工作流状态', description: '工作流状态机' },
    { id: 'custom', name: '自定义状态', description: '用户自定义的状态' }
  ],
  lifeline: [
    { id: 'actor', name: '参与者', description: '系统参与者' },
    { id: 'system', name: '系统', description: '系统组件' },
    { id: 'custom', name: '自定义生命线', description: '用户自定义的生命线' }
  ]
})

let elementCounter = 0

// 模板数据 - 使用导入的模板映射
const templates = ref(getAllTemplates())

const getTemplates = () => {
  const map = templates.value || {}
  const entries = Object.keys(map).map((diagramTypeKey) => {
    const tpl = map[diagramTypeKey]
    const nameMap = {
      class: '基础类图',
      activity: '活动图',
      sequence: '时序图',
      usecase: '用例图',
      state: '状态图'
    }
    return {
      id: diagramTypeKey,
      name: nameMap[diagramTypeKey] || diagramTypeKey,
      description: '内置模板',
      // 简单的占位预览
      preview: 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="150"><rect width="200" height="150" fill="white"/><text x="100" y="75" text-anchor="middle">' + (nameMap[diagramTypeKey] || diagramTypeKey) + '</text></svg>',
      diagramType: diagramTypeKey,
      elements: tpl?.elements || []
    }
  })
  return entries.filter(e => e.diagramType === currentDiagramType.value)
}

// 停止执行动画
const stopExecution = () => {
  isExecuting.value = false
  executionPath.value = []
  executedNodeIds.value = new Set()
  animation.value = { running: false, progress: 0, dashOffset: 0, relIndex: 0 }
  cancelAnimationFrame(animationFrameId)
  redrawCanvas()
}

const loadTemplate = (template) => {
  if (!template) return
  clearAll()
  const type = template.diagramType || template.type || currentDiagramType.value
  currentDiagramType.value = type
  elements.value = JSON.parse(JSON.stringify(template.elements || []))
  // 设置默认标题为当前图表类型名称
  diagramTitle.value = getDiagramTypeTitle(type)
  showTemplateModal.value = false
  stopExecution()
  generateUML()
}

const clearAll = () => {
  elements.value = []
  selectedElement.value = null
  umlImageUrl.value = ''
  error.value = ''
  // 设置默认标题为当前图表类型名称，而不是清空
  diagramTitle.value = getDiagramTypeTitle(currentDiagramType.value)
  stopExecution()
}

const onDiagramTypeChange = () => {
  selectedElement.value = null
  clearAll()
  // 设置默认标题为当前图表类型名称
  diagramTitle.value = getDiagramTypeTitle(currentDiagramType.value)
  stopExecution()
  generateUML()
}

const getLibraryElements = () => {
  switch (currentDiagramType.value) {
    case 'class':
      return [
        { type: 'class', label: '类' },
        { type: 'interface', label: '接口' },
        { type: 'enum', label: '枚举' }
      ]
    case 'activity':
      return [
        { type: 'activity', activityType: 'start', label: '开始' },
        { type: 'activity', activityType: 'end', label: '结束' },
        { type: 'activity', activityType: 'action', label: '动作' },
        { type: 'activity', activityType: 'decision', label: '决策' },
        { type: 'activity', activityType: 'merge', label: '合并' },
        { type: 'activity', activityType: 'fork', label: '分叉' },
        { type: 'activity', activityType: 'join', label: '汇合' },
        { type: 'activity', activityType: 'note', label: '注释' },
        { type: 'activity', activityType: 'partition', label: '分区' },
        { type: 'activity', activityType: 'repeat', label: '循环' },
        { type: 'activity', activityType: 'break', label: '跳出' },
        { type: 'activity', activityType: 'switch', label: '分支' },
        { type: 'activity', activityType: 'case', label: '分支项' },
        { type: 'activity', activityType: 'endswitch', label: '结束分支' },
        { type: 'activity', activityType: 'condition', label: '条件判断' },
        { type: 'activity', activityType: 'else', label: '否则' },
        { type: 'activity', activityType: 'endif', label: '结束判断' },
        { type: 'activity', activityType: 'while', label: '循环判断' },
        { type: 'activity', activityType: 'endwhile', label: '结束循环' }
      ]
    case 'sequence':
      return [
        { type: 'lifeline', participantType: 'actor', label: '角色' },
        { type: 'lifeline', participantType: 'participant', label: '参与者' },
        { type: 'lifeline', participantType: 'boundary', label: '边界' },
        { type: 'lifeline', participantType: 'control', label: '控制' },
        { type: 'lifeline', participantType: 'entity', label: '实体' },
        { type: 'lifeline', participantType: 'database', label: '数据库' }
      ]
    case 'usecase':
      return [
        { type: 'usecase', usecaseType: 'actor', label: '角色' },
        { type: 'usecase', usecaseType: 'usecase', label: '用例' },
        { type: 'usecase', usecaseType: 'system', label: '系统' }
      ]
    case 'state':
      return [
        { type: 'state', stateType: 'initial', label: '初始状态' },
        { type: 'state', stateType: 'final', label: '最终状态' },
        { type: 'state', stateType: 'state', label: '状态' },
        { type: 'state', stateType: 'composite', label: '复合状态' }
      ]
    default:
      return []
  }
}

// 拖拽相关方法
const onDragStart = (event, element) => {
  isDragging.value = true
  dragElement.value = element
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'copy'
    event.dataTransfer.setData('text/plain', JSON.stringify(element))
  }
}

const onDragEnd = () => {
  isDragging.value = false
  dragElement.value = null
}

const onDragOver = (event) => {
  event.preventDefault()
  if (event.dataTransfer) {
    event.dataTransfer.dropEffect = 'copy'
  }
}

const onDrop = (event) => {
  event.preventDefault()
  isDragging.value = false

  const rect = event.target.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top

  if (dragElement.value) {
    addElementAtPosition(dragElement.value, x, y)
  }

  dragElement.value = null
}

const addElementAtPosition = (elementData, x, y) => {
  if (props.useModel) {
    // 如果启用模型功能，显示模型选择对话框
    pendingElementData.value = elementData
    pendingPosition.value = { x, y }
    selectedModel.value = ''
    showModelSelectionModal.value = true
    stopExecution()
  } else {
    // 如果不启用模型功能，直接添加元素
    const newElement = {
      ...elementData,
      id: `element${elementCounter++}`,
      x: (x - canvasTranslateX.value) / canvasScale.value,
      y: (y - canvasTranslateY.value) / canvasScale.value,
      name: elementData.label || elementData.type
    }
    
    elements.value.push(newElement)
    redrawCanvas()
    generateUML()
  }
}

// 元素移动相关方法
const startElementDrag = (event, element) => {
  isMovingElement.value = true
  movingElement.value = element

  // 计算鼠标相对于元素的偏移量，考虑画布的缩放和平移
  const rect = canvas.value.getBoundingClientRect()
  const x = (event.clientX - rect.left - canvasTranslateX.value) / canvasScale.value
  const y = (event.clientY - rect.top - canvasTranslateY.value) / canvasScale.value

  moveStartPosition.value = {
    x: x - element.x,
    y: y - element.y
  }

  event.preventDefault()
  event.stopPropagation()
}

const stopElementDrag = () => {
  if (movingElement.value) {
    // 拖动结束后更新UML图
    generateUML()
  }

  isMovingElement.value = false
  movingElement.value = null
}

const onCanvasMouseMove = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const x = (event.clientX - rect.left - canvasTranslateX.value) / canvasScale.value
  const y = (event.clientY - rect.top - canvasTranslateY.value) / canvasScale.value

  if (isPanning.value) {
    const deltaX = event.clientX - panStartPosition.value.x
    const deltaY = event.clientY - panStartPosition.value.y
    canvasTranslateX.value += deltaX
    canvasTranslateY.value += deltaY
    panStartPosition.value = { x: event.clientX, y: event.clientY }
    redrawCanvas()
  } else if (isMovingElement.value && movingElement.value) {
    movingElement.value.x = x - moveStartPosition.value.x
    movingElement.value.y = y - moveStartPosition.value.y
    redrawCanvas()
  } else if (isConnecting.value) {
    // 更新连线终点
    connectionEnd.value = { x, y }
    redrawCanvas()
  }
}

const onCanvasMouseLeave = (event) => {
  // 当鼠标离开画布区域时，结束所有拖拽操作
  if (canvas.value) {
    canvas.value.classList.remove('dragging', 'connecting', 'selecting')
  }

  // 重置所有拖拽相关状态
  if (isPanning.value) {
    isPanning.value = false
  }
  
  if (isMovingElement.value) {
    stopElementDrag()
  }
  
  if (isConnecting.value) {
    isConnecting.value = false
    connectingElement.value = null
  }
  
  if (isDragging.value) {
    isDragging.value = false
    dragElement.value = null
  }
  
  // 确保重绘画布以更新视图
  redrawCanvas()
}

const onCanvasMouseUp = (event) => {
  // 移除拖拽样式
  if (canvas.value) {
    canvas.value.classList.remove('dragging', 'connecting')
  }

  if (isPanning.value) {
    isPanning.value = false
  } else if (isMovingElement.value) {
    stopElementDrag()
  } else if (isConnecting.value) {
    const rect = canvas.value.getBoundingClientRect()
    const x = (event.clientX - rect.left - canvasTranslateX.value) / canvasScale.value
    const y = (event.clientY - rect.top - canvasTranslateY.value) / canvasScale.value

    // 查找目标元素
    const targetElement = findElementAtPosition(x, y)
    if (targetElement && targetElement.id !== connectingElement.value.id) {
      // 创建关系
      createRelationship(connectingElement.value, targetElement)
    }

    // 结束连线操作
    isConnecting.value = false
    connectingElement.value = null
    connectingPoint.value = ''
    redrawCanvas()
  }
}

// 查找指定位置的元素
const findElementAtPosition = (x, y) => {
  for (let i = elements.value.length - 1; i >= 0; i--) {
    const element = elements.value[i]

    if (element.type === 'relationship') {
      // 检查是否点击了关系线
      const relationship = findRelationshipAtPosition(element, x, y)
      if (relationship) {
        return relationship
      }
      continue
    }

    const width = getElementWidth(element)
    const height = getElementHeight(element)

    // 扩展检测区域，包括选中框
    const padding = element.selected ? 8 : 0
    const expandedX = element.x - padding
    const expandedY = element.y - padding
    const expandedWidth = width + padding * 2
    const expandedHeight = height + padding * 2

    if (x >= expandedX && x <= expandedX + expandedWidth &&
      y >= expandedY && y <= expandedY + expandedHeight) {

      // 如果元素被选中，检查是否点击了连接点
      if (element.selected) {
        const connectionPoint = findConnectionPointAtPosition(element, x, y)
        if (connectionPoint) {
          return { ...element, connectionPoint }
        }
      }

      return element
    }
  }
  return null
}

// 查找指定位置的连接点
const findConnectionPointAtPosition = (element, x, y) => {
  const width = getElementWidth(element)
  const height = getElementHeight(element)
  const pointRadius = 6

  const points = [
    { x: element.x + width / 2, y: element.y - pointRadius, side: 'top' },
    { x: element.x + width + pointRadius, y: element.y + height / 2, side: 'right' },
    { x: element.x + width / 2, y: element.y + height + pointRadius, side: 'bottom' },
    { x: element.x - pointRadius, y: element.y + height / 2, side: 'left' }
  ]

  for (const point of points) {
    const distance = Math.sqrt(Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2))
    if (distance <= pointRadius) {
      return point
    }
  }

  return null
}

const deselectElement = () => {
  elements.value.forEach(el => el.selected = false)
  selectedElement.value = null
}

const selectElement = (element) => {
  // 清除之前的选择
  elements.value.forEach(el => el.selected = false)

  // 设置新选择
  element.selected = true
  selectedElement.value = element
}

const deleteElement = (id) => {
  const elementToDelete = elements.value.find(el => el.id === id)

  if (elementToDelete) {
    // 如果是关系线，直接删除
    if (elementToDelete.type === 'relationship') {
      elements.value = elements.value.filter(el => el.id !== id)
      if (selectedElement.value?.id === id) {
        selectedElement.value = null
      }
      stopExecution()
      generateUML()
      ElMessage.success('已删除关系')
      return
    }

    // 如果是元素，需要删除相关的所有关系线
    const relatedRelationships = elements.value.filter(el =>
      el.type === 'relationship' &&
      (el.sourceId === id || el.targetId === id)
    )

    // 删除相关的关系线
    relatedRelationships.forEach(relationship => {
      elements.value = elements.value.filter(el => el.id !== relationship.id)
    })

    // 删除元素本身
    elements.value = elements.value.filter(el => el.id !== id)

    // 清理选择状态
    if (selectedElement.value?.id === id) {
      selectedElement.value = null
    }

    // 显示删除消息
    const deletedCount = relatedRelationships.length
    if (deletedCount > 0) {
      ElMessage.success(`已删除元素和 ${deletedCount} 个相关关系`)
    } else {
      ElMessage.success('已删除元素')
    }

    stopExecution()
    generateUML()
  }
}

const addAttribute = () => {
  if (selectedElement.value && (selectedElement.value.type === 'class' || selectedElement.value.type === 'interface' || selectedElement.value.type === 'enum')) {
    selectedElement.value.attributes.push({
      name: '',
      type: '',
      visibility: 'public'
    })
    updateElement()
  }
}

const removeAttribute = (index) => {
  if (selectedElement.value) {
    selectedElement.value.attributes.splice(index, 1)
    updateElement()
  }
}

const addMethod = () => {
  if (selectedElement.value && (selectedElement.value.type === 'class' || selectedElement.value.type === 'interface')) {
    selectedElement.value.methods.push({
      name: '',
      returnType: 'void',
      visibility: 'public'
    })
    updateElement()
  }
}

const removeMethod = (index) => {
  if (selectedElement.value) {
    selectedElement.value.methods.splice(index, 1)
    updateElement()
  }
}

const updateElement = () => {
  stopExecution()
  generateUML()
}

const getConnectableElements = () => {
  return elements.value.filter(el => el.type !== 'relationship')
}

const getRelationships = () => {
  return elements.value.filter(el => el.type === 'relationship')
}

const getElementStyle = (element) => {
  return {
    left: `${element.x + 20}px`, // 考虑画布内容的padding
    top: `${element.y + 20}px`   // 考虑画布内容的padding
  }
}

// 使用导入的getVisibilitySymbol函数

const getRelationshipStart = (relationship) => {
  const source = elements.value.find(el => el.id === relationship.sourceId)
  const target = elements.value.find(el => el.id === relationship.targetId)

  if (!source || !target) return { x: 0, y: 0 }

  // 计算两个元素的中心点
  const sourceCenter = getElementCenter(source)
  const targetCenter = getElementCenter(target)

  // 计算源元素的边界点（从目标中心到源中心的连线与源元素边界的交点）
  const sourceEdge = getElementEdgePoint(targetCenter, sourceCenter, source, 'source')

  return sourceEdge
}

const getRelationshipEnd = (relationship) => {
  const source = elements.value.find(el => el.id === relationship.sourceId)
  const target = elements.value.find(el => el.id === relationship.targetId)

  if (!source || !target) return { x: 0, y: 0 }

  // 计算两个元素的中心点
  const sourceCenter = getElementCenter(source)
  const targetCenter = getElementCenter(target)

  // 计算目标元素的边界点
  const targetEdge = getElementEdgePoint(targetCenter, sourceCenter, target, 'target')

  return targetEdge
}

// 使用导入的getElementCenter和getElementEdgePoint函数

const getRelationshipTypes = () => {
  switch (currentDiagramType.value) {
    case 'class':
      return [
        { value: 'association', label: '关联' },
        { value: 'inheritance', label: '继承' },
        { value: 'implementation', label: '实现' },
        { value: 'composition', label: '组合' },
        { value: 'aggregation', label: '聚合' },
        { value: 'dependency', label: '依赖' }
      ]
    case 'activity':
    case 'data_flow':
      return [
        { value: 'association', label: '控制流' },
        { value: 'dependency', label: '数据流' }
      ]
    case 'sequence':
      return [
        { value: 'association', label: '消息' },
        { value: 'dependency', label: '返回' }
      ]
    case 'usecase':
      return [
        { value: 'association', label: '关联' },
        { value: 'inheritance', label: '泛化' },
        { value: 'dependency', label: '包含' },
        { value: 'realization', label: '扩展' }
      ]
    case 'state':
      return [
        { value: 'association', label: '转换' },
        { value: 'dependency', label: '嵌套' }
      ]
    default:
      return []
  }
}

const generateUML = async () => {
  if (elements.value.length === 0) {
    umlImageUrl.value = ''
    return
  }

  loading.value = true
  error.value = ''

  try {
    const plantUMLCode = generatePlantUMLCodeLocal()
    
    // 使用提取的API服务
    const blobData = await generateUMLImage(plantUMLCode)
    
    // 创建blob URL
    const blob = new Blob([blobData], { type: 'image/png' })
    const imageUrl = URL.createObjectURL(blob)

    umlImageUrl.value = imageUrl
    loading.value = false
  } catch (err) {
    console.error('生成UML图时发生错误:', err)
    error.value = '无法生成UML图，请检查元素配置或服务连接'
    loading.value = false
  }
}

const generatePlantUMLCodeLocal = () => {
  return generatePlantUMLCode(elements.value, currentDiagramType.value, diagramTitle.value)
}

// 使用导入的getDiagramTypeTitle函数

// 使用导入的UML生成函数

const handleImageError = () => {
  error.value = '图片加载失败，请检查网络连接'
}

const autoLayout = () => {
  const cols = Math.ceil(Math.sqrt(elements.value.length))
  elements.value.forEach((element, index) => {
    const row = Math.floor(index / cols)
    const col = index % cols
    element.x = 150 + col * 200
    element.y = 150 + row * 150
  })
  generateUML()
}

// 执行：UI
const activityStartNodes = computed(() => elements.value.filter(el => el.type === 'activity' && el.activityType === 'start'))
const openExecutionDialog = () => {
  if (currentDiagramType.value !== 'activity') return
  const starts = activityStartNodes.value
  executionParams.value.startId = starts[0]?.id || ''
  executionParams.value.branchChoices = ''
  showExecutionDialog.value = true
}

// 执行：路径计算（简单分支解析：依赖关系 name 作为选择标签，如 yes/no）
const computeExecutionPath = (startId, choices) => {
  const rels = elements.value.filter(el => el.type === 'relationship' && el.relationshipType === 'association')
  const nextOf = (nodeId) => rels.filter(r => r.sourceId === nodeId)
  const choiceQueue = [...choices]
  const path = []
  const visitedNodes = new Set()
  let current = startId
  let guard = 0
  while (current && guard++ < 1000) {
    visitedNodes.add(current)
    const outs = nextOf(current)
    if (outs.length === 0) break
    let picked
    if (outs.length === 1) {
      picked = outs[0]
    } else {
      // 若提供分支选择，则匹配关系名；否则取第一条
      const choice = choiceQueue.length > 0 ? choiceQueue.shift().trim().toLowerCase() : ''
      if (choice) {
        // 尝试多种匹配方式
        picked = outs.find(o => {
          const relName = (o.name || '').trim().toLowerCase()
          // 1. 直接匹配关系名称
          if (relName === choice) return true
          // 2. 匹配常见分支模式
          if (choice === 'yes' && (relName === 'yes' || relName === 'true' || relName === '成功' || relName === '通过')) return true
          if (choice === 'no' && (relName === 'no' || relName === 'false' || relName === '失败' || relName === '不通过')) return true
          // 3. 如果没有名称，按位置匹配（第一个为yes，第二个为no）
          return false
        })

        // 如果没找到匹配的名称，按位置匹配（假设第一个分支是yes，第二个是no）
        if (!picked && outs.length === 2) {
          if (choice === 'yes' || choice === 'true' || choice === '成功' || choice === '通过') {
            picked = outs[0] // 第一个分支
          } else if (choice === 'no' || choice === 'false' || choice === '失败' || choice === '不通过') {
            picked = outs[1] // 第二个分支
          }
        }
      }

      // 如果还是没有找到，取第一条
      if (!picked) {
        picked = outs[0]
      }
    }
    path.push(picked.id)
    const nextNode = elements.value.find(el => el.id === picked.targetId)
    if (!nextNode || visitedNodes.has(nextNode.id)) break
    current = nextNode.id
    // 记录经过节点
    executedNodeIds.value.add(nextNode.id)
    if (nextNode.type === 'activity' && (nextNode.activityType === 'end')) break
  }
  return path
}

// 执行：开始
const startExecution = () => {
  if (!executionParams.value.startId) {
    ElMessage.warning('请选择开始节点')
    return
  }
  executedNodeIds.value = new Set([executionParams.value.startId])
  const choices = executionParams.value.branchChoices
    ? executionParams.value.branchChoices.split(',')
    : []
  executionPath.value = computeExecutionPath(executionParams.value.startId, choices)
  if (executionPath.value.length === 0) {
    ElMessage.info('未找到可执行路径')
    showExecutionDialog.value = false
    return
  }
  // 初始化动画状态
  animation.value = { running: true, progress: 0, dashOffset: 0, relIndex: 0 }
  isExecuting.value = true
  showExecutionDialog.value = false
  cancelAnimationFrame(animationFrameId)
  animationFrameId = requestAnimationFrame(tick)
}

// 重播
const replayExecution = () => {
  if (executionPath.value.length === 0) return
  executedNodeIds.value = new Set([executionParams.value.startId])
  animation.value = { running: true, progress: 0, dashOffset: 0, relIndex: 0 }
  isExecuting.value = true
  cancelAnimationFrame(animationFrameId)
  animationFrameId = requestAnimationFrame(tick)
}

const generateRelationships = () => {
  const connectableElements = getConnectableElements()
  if (connectableElements.length >= 2) {
    // 先移除所有现有的关系线
    elements.value = elements.value.filter(el => el.type !== 'relationship')

    // 生成新的关系线
    for (let i = 0; i < connectableElements.length - 1; i++) {
      const newRelationship = {
        id: `element_${++elementCounter}`,
        name: `Relationship${elementCounter}`,
        type: 'relationship',
        x: 0,
        y: 0,
        attributes: [],
        methods: [],
        relationshipType: 'association',
        sourceId: connectableElements[i].id,
        targetId: connectableElements[i + 1].id
      }
      elements.value.push(newRelationship)
    }
    generateUML()
  }
}

const exportCode = () => {
  const code = generatePlantUMLCodeLocal()
  const blob = new Blob([code], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `uml-${currentDiagramType.value}-${Date.now()}.puml`
  a.click()
  URL.revokeObjectURL(url)
}

// 连接相关方法
const startConnection = (event, element, side) => {
  isConnecting.value = true
  const rect = event.currentTarget.getBoundingClientRect()
  const canvasRect = event.currentTarget.closest('.canvas')?.getBoundingClientRect()

  if (canvasRect) {
    let startX = element.x + 75 // 假设元素宽度为150的一半
    let startY = element.y + 50  // 假设元素高度为100的一半

    // 根据连接点位置调整起始坐标
    switch (side) {
      case 'top':
        startY = element.y
        break
      case 'right':
        startX = element.x + 150
        break
      case 'bottom':
        startY = element.y + 100
        break
      case 'left':
        startX = element.x
        break
    }

    connectionStart.value = {
      x: startX,
      y: startY,
      elementId: element.id
    }
    connectionEnd.value = { x: startX, y: startY }
  }

  event.preventDefault()
  event.stopPropagation()
}

onMounted(() => {
  // 初始化时只设置默认标题，不加载默认模板
  diagramTitle.value = getDiagramTypeTitle(currentDiagramType.value)

  // 添加键盘事件监听
  document.addEventListener('keydown', handleKeyDown)

  // 添加点击其他地方关闭右键菜单
  document.addEventListener('click', closeContextMenu)
})

// 清理事件监听
onUnmounted(() => {
  document.removeEventListener('keydown', handleKeyDown)
  document.removeEventListener('click', closeContextMenu)
})

// 关闭右键菜单
const closeContextMenu = () => {
  showContextMenuFlag.value = false
}

// 键盘事件处理
const handleKeyDown = (event) => {
  if (event.key === 'Delete') {
    if (selectedElement.value) {
      deleteElement(selectedElement.value.id)
    }
  }
  // 执行快捷键：Ctrl/Cmd + Enter（仅活动图）
  if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
    if (currentDiagramType.value === 'activity') {
      openExecutionDialog()
    }
  }
}

// 实时预览功能 - 当元素变化时自动更新UML图，但拖动时不更新
watch([elements, currentDiagramType], () => {
  if (elements.value.length > 0 && !isMovingElement.value && !isDragging.value) {
    generateUML()
  } else if (elements.value.length === 0) {
    umlImageUrl.value = ''
    error.value = ''
  }
}, { deep: true })

// 监听标题变化，实时更新预览
watch(diagramTitle, () => {
  if (elements.value.length > 0 && !isMovingElement.value && !isDragging.value) {
    generateUML()
  }
})

// 执行动画心跳
let animationFrameId = 0
const tick = () => {
  if (!isExecuting.value) return
  animation.value.dashOffset += 2
  animation.value.progress += 0.02
  if (animation.value.progress >= 1) {
    animation.value.progress = 0
    animation.value.relIndex += 1
    if (animation.value.relIndex >= executionPath.value.length) {
      if (loopExecution.value) {
        // 循环播放：重置状态，保留路径与节点高亮
        animation.value.relIndex = 0
        executedNodeIds.value = new Set([executionParams.value.startId])
      } else {
        // 结束
        isExecuting.value = false
        cancelAnimationFrame(animationFrameId)
        redrawCanvas()
        return
      }
    }
  }
  redrawCanvas()
  animationFrameId = requestAnimationFrame(tick)
}

const downloadImage = () => {
  const link = document.createElement('a')
  link.href = umlImageUrl.value
  link.download = `uml-${currentDiagramType.value}-${Date.now()}.png`
  link.click()
}

const refreshPreview = () => {
  generateUML()
}

const showContextMenuHandler = (event, element) => {
  event.preventDefault()
  selectedElement.value = element
  showContextMenuFlag.value = true
  contextMenuStyle.value = {
    left: event.clientX + 'px',
    top: event.clientY + 'px'
  }
}

const deleteSelectedElement = () => {
  if (selectedElement.value) {
    const elementType = selectedElement.value.type === 'relationship' ? '关系' : '元素'
    const elementName = selectedElement.value.name || `未命名的${elementType}`
    const elementId = selectedElement.value.id // 先保存元素ID

    ElMessageBox.confirm(
      `确定要删除${elementType} "${elementName}" 吗？`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    ).then(() => {
      // 用户确认删除，使用nextTick确保在下一个tick中执行
      nextTick(() => {
        try {
          deleteElement(elementId)
          showContextMenuFlag.value = false
        } catch (error) {
          console.error('删除元素时出错:', error)
          ElMessage.error('删除失败，请重试')
        }
      })
    }).catch(() => {
      // 用户取消删除
      ElMessage.info('已取消删除')
    })
  }
}

const copyElement = () => {
  if (selectedElement.value) {
    const newElement = { ...selectedElement.value }
    newElement.id = `element_${++elementCounter}`
    newElement.x += 50
    newElement.y += 50
    elements.value.push(newElement)
    selectedElement.value = newElement
    showContextMenuFlag.value = false
  }
}

// 开始平移
const startPanning = (event) => {
  isPanning.value = true
  panStartPosition.value = { x: event.clientX, y: event.clientY }
}

// 缩放控制（已在Canvas相关状态部分定义）

// 缩放控制函数
const zoomIn = () => {
  canvasScale.value = Math.min(3, canvasScale.value * 1.2)
  redrawCanvas()
}

const zoomOut = () => {
  canvasScale.value = Math.max(0.1, canvasScale.value * 0.8)
  redrawCanvas()
}

const resetView = () => {
  canvasScale.value = 1
  canvasTranslateX.value = 0
  canvasTranslateY.value = 0
  redrawCanvas()
}

// 创建关系
const createRelationship = (source, target) => {
  // 验证源和目标元素
  if (!source || !target || source.id === target.id) {
    console.warn('Invalid source or target for relationship')
    return
  }

  // 检查是否已经存在相同的关系
  const existingRelationship = elements.value.find(el =>
    el.type === 'relationship' &&
    el.sourceId === source.id &&
    el.targetId === target.id
  )

  if (existingRelationship) {
    ElMessage.warning('这两个元素之间已经存在关系')
    return
  }

  const newRelationship = {
    id: `relationship_${++elementCounter}`,
    type: 'relationship',
    sourceId: source.id,
    targetId: target.id,
    relationshipType: currentRelationshipType.value,
    selected: false,
    name: `${getRelationshipTypeName(currentRelationshipType.value)}关系`
  }

  console.log('Creating relationship:', newRelationship)
  elements.value.push(newRelationship)

  // 立即重绘画布以显示关系线
  redrawCanvas()
  stopExecution()
  generateUML()

  // 显示成功消息
  ElMessage.success(`已创建 ${getRelationshipTypeName(currentRelationshipType.value)} 关系`)
}

// 监听元素变化，重绘画布
watch(elements, () => {
  redrawCanvas()
}, { deep: true })

// 监听选择状态变化
watch(selectedElement, () => {
  redrawCanvas()
})

// 组件挂载时初始化Canvas
onMounted(() => {
  nextTick(() => {
    initCanvas()
    redrawCanvas()
  })
})

// 组件卸载时清理
onUnmounted(() => {
  // 清理Canvas上下文
  if (ctx.value) {
    ctx.value = null
  }

  // 清理画布样式类
  if (canvas.value) {
    canvas.value.classList.remove('dragging', 'selecting', 'connecting')
  }
})



// 初始化Canvas
const initCanvas = () => {
  if (!canvas.value) return

  const canvasEl = canvas.value
  const rect = canvasEl.getBoundingClientRect()
  canvasWidth.value = rect.width
  canvasHeight.value = rect.height

  // 设置Canvas尺寸
  canvasEl.width = canvasWidth.value
  canvasEl.height = canvasHeight.value

  ctx.value = canvasEl.getContext('2d')
  isCanvasInitialized.value = true

  // 绘制初始网格
  drawGrid(ctx.value, canvasWidth.value, canvasHeight.value, canvasTranslateX.value, canvasTranslateY.value)
}


// 清空Canvas
const clearCanvas = () => {
  if (!ctx.value) return
  ctx.value.clearRect(0, 0, canvasWidth.value, canvasHeight.value)
}

// 应用Canvas变换
const applyTransform = () => {
  if (!ctx.value) return
  ctx.value.save()
  ctx.value.translate(canvasTranslateX.value, canvasTranslateY.value)
  ctx.value.scale(canvasScale.value, canvasScale.value)
}

// 恢复Canvas变换
const restoreTransform = () => {
  if (!ctx.value) return
  ctx.value.restore()
}

// 绘制元素
const drawElement = (element) => {
  if (!ctx.value) return

  const x = element.x
  const y = element.y
  const width = getElementWidth(element)
  const height = getElementHeight(element)

  ctx.value.save()

  // 绘制阴影
  ctx.value.shadowColor = 'rgba(0, 0, 0, 0.2)'
  ctx.value.shadowBlur = 8
  ctx.value.shadowOffsetX = 2
  ctx.value.shadowOffsetY = 2

  // 根据元素类型绘制不同的形状
  if (element.type === 'activity') {
    drawActivityElement(ctx.value, element, x, y, width, height)
  } else if (element.type === 'lifeline') {
    drawLifelineElement(ctx.value, element, x, y, width, height)
  } else if (element.type === 'class' || element.type === 'interface' || element.type === 'enum') {
    // 优雅样式的类图/接口/枚举
    drawClassElement(ctx.value, element, x, y, width, height)
  } else if (element.type === 'state') {
    // 为状态图元素绘制特殊样式
    drawStateElement(ctx.value, element, x, y, width, height)
  } else if (element.type === 'usecase') {
    // 为用例图元素绘制特殊样式
    drawUseCaseElement(ctx.value, element, x, y, width, height)
  } else {
    // 绘制圆角矩形背景（默认形状）
    drawRoundedRectangle(ctx.value, x, y, width, height, 8)
  }

  // 如果元素被选中，绘制选中框
  if (element.selected) {
    drawSelectionBox(ctx.value, x, y, width, height)
  }

  // 绘制连接点（当元素被选中时）
  if (element.selected) {
    drawConnectionPoints(ctx.value, element, x, y, width, height)
  }

  // 绘制标题栏和内容
  if (element.type !== 'class' && element.type !== 'interface' && element.type !== 'enum') {
    drawElementContent(ctx.value, element, x, y, width, height)
  }

  ctx.value.restore()
}



// 使用导入的getElementWidth和getElementHeight函数

// 重绘画布
const redrawCanvas = () => {
  if (!isCanvasInitialized.value) return

  clearCanvas()
  drawGrid(ctx.value, canvasWidth.value, canvasHeight.value, canvasTranslateX.value, canvasTranslateY.value)
  applyTransform()

  // 绘制元素（在关系线下方）
  elements.value.filter(el => el.type !== 'relationship').forEach(drawElement)

  // 绘制关系线（在元素上方）
  const relationships = elements.value.filter(el => el.type === 'relationship')
  if (relationships.length > 0) {
    console.log('Found relationships:', relationships.length)
    relationships.forEach((relationship) => {
      const source = elements.value.find(el => el.id === relationship.sourceId)
      const target = elements.value.find(el => el.id === relationship.targetId)
      if (source && target) {
        const highlightIndex = executionPath.value.indexOf(relationship.id)
        const isActive = isExecuting.value && highlightIndex > -1 && highlightIndex <= animation.value.relIndex
        if (isActive) {
          const isCurrent = highlightIndex === animation.value.relIndex
          if (isCurrent) {
            drawHighlightedRelationship(ctx.value, relationship, source, target, animation.value.progress, animation.value.dashOffset)
          } else {
            drawHighlightedRelationship(ctx.value, relationship, source, target, 1, animation.value.dashOffset)
          }
        } else {
          drawRelationship(ctx.value, relationship, source, target)
        }
      }
    })
  }

  // 绘制连接中的线条
  if (isConnecting.value) {
    drawConnectingLine(ctx.value, connectionStart.value, connectionEnd.value)
  }

  // 高亮已执行的节点
  if (isExecuting.value && executedNodeIds.value.size > 0) {
    elements.value.filter(el => el.type !== 'relationship' && executedNodeIds.value.has(el.id))
      .forEach(el => {
        const w = getElementWidth(el)
        const h = getElementHeight(el)
        drawElementHighlight(ctx.value, el.x, el.y, w, h)
      })
  }

  restoreTransform()
}


const onCanvasMouseDown = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const x = (event.clientX - rect.left - canvasTranslateX.value) / canvasScale.value
  const y = (event.clientY - rect.top - canvasTranslateY.value) / canvasScale.value

  // 记录鼠标按下时的位置
  panStartPosition.value = { x: event.clientX, y: event.clientY }

  // 检查是否点击了元素
  const clickedElement = findElementAtPosition(x, y)
  if (clickedElement) {
    if (event.button === 0) { // 左键
      // 检查是否点击了连接点
      if (clickedElement.connectionPoint) {
        // 开始连线操作
        isConnecting.value = true
        connectingElement.value = clickedElement
        connectingPoint.value = clickedElement.connectionPoint.side

        // 设置连线起始点
        connectionStart.value = {
          x: clickedElement.connectionPoint.x,
          y: clickedElement.connectionPoint.y,
          elementId: clickedElement.id
        }
        connectionEnd.value = { x: clickedElement.connectionPoint.x, y: clickedElement.connectionPoint.y }

        // 更新画布样式
        if (canvas.value) {
          canvas.value.classList.add('connecting')
        }

        event.preventDefault()
        event.stopPropagation()
        return
      }

      // 检查是否点击了关系线
      if (clickedElement.type === 'relationship') {
        // 选中关系线
        selectElement(clickedElement)
        event.preventDefault()
        event.stopPropagation()
        return
      }

      // 直接选中元素
      selectElement(clickedElement)

      // 开始拖拽
      isMovingElement.value = true
      movingElement.value = clickedElement

      // 计算鼠标相对于元素的偏移量
      moveStartPosition.value = {
        x: x - clickedElement.x,
        y: y - clickedElement.y
      }

      // 更新画布样式
      if (canvas.value) {
        canvas.value.classList.add('dragging')
      }

      event.preventDefault()
      event.stopPropagation()
    }
  } else {
    // 点击空白区域，清除选择
    deselectElement()
    if (event.button === 0) { // 左键
      startPanning(event)
    }
  }
}

const onCanvasWheel = (event) => {
  event.preventDefault()

  if (event.ctrlKey) {
    // 缩放
    const delta = event.deltaY > 0 ? 0.9 : 1.1
    const newScale = Math.max(0.1, Math.min(3, canvasScale.value * delta))
    canvasScale.value = newScale
  } else {
    // 平移
    canvasTranslateX.value -= event.deltaX
    canvasTranslateY.value -= event.deltaY
  }

  redrawCanvas()
}

const exportCanvas = () => {
  // 检查是否有内容可导出
  if (elements.value.length === 0) {
    ElMessage.warning('画布为空，没有内容可导出')
    return
  }

  try {
    // 准备导出的数据
    const exportData = {
      version: '1.0',
      timestamp: new Date().toISOString(),
      diagramType: currentDiagramType.value,
      canvasScale: canvasScale.value,
      canvasTranslateX: canvasTranslateX.value,
      canvasTranslateY: canvasTranslateY.value,
      elements: elements.value,
      metadata: {
        totalElements: elements.value.length,
        relationships: elements.value.filter(el => el.type === 'relationship').length,
        classes: elements.value.filter(el => el.type === 'class').length,
        interfaces: elements.value.filter(el => el.type === 'interface').length,
        activities: elements.value.filter(el => el.type === 'activity').length,
        usecases: elements.value.filter(el => el.type === 'usecase').length,
        states: elements.value.filter(el => el.type === 'state').length,
        lifelines: elements.value.filter(el => el.type === 'lifeline').length
      }
    }

    // 创建JSON字符串
    const jsonString = JSON.stringify(exportData, null, 2)

    // 创建Blob对象
    const blob = new Blob([jsonString], { type: 'application/json' })

    // 创建下载链接
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `uml-diagram-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.json`

    // 触发下载
    document.body.appendChild(link)
    link.click()

    // 清理
    document.body.removeChild(link)
    URL.revokeObjectURL(url)

    // 显示成功消息
    const elementCount = elements.value.length
    const relationshipCount = elements.value.filter(el => el.type === 'relationship').length
    ElMessage.success(`成功导出 ${elementCount} 个元素（包含 ${relationshipCount} 个关系）`)

  } catch (error) {
    console.error('导出文件时出错:', error)
    ElMessage.error('导出失败，请重试')
  }
}

const importCanvas = () => {
  // 如果当前画布有内容，显示确认对话框
  if (elements.value.length > 0) {
    ElMessageBox.confirm(
      '导入新内容将覆盖当前画布上的所有元素，是否继续？',
      '确认导入',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    ).then(() => {
      // 用户确认，触发文件选择
      if (fileInput.value) {
        fileInput.value.click()
      }
    }).catch(() => {
      // 用户取消
      ElMessage.info('已取消导入')
    })
  } else {
    // 画布为空，直接触发文件选择
    if (fileInput.value) {
      fileInput.value.click()
    }
  }
}

const handleFileImport = (event) => {
  const file = event.target.files[0]
  if (!file) return

  // 检查文件类型
  if (!file.name.endsWith('.json')) {
    ElMessage.error('请选择JSON文件')
    return
  }

  // 检查文件大小（限制为10MB）
  if (file.size > 10 * 1024 * 1024) {
    ElMessage.error('文件大小不能超过10MB')
    return
  }

  const reader = new FileReader()
  reader.onload = (e) => {
    try {
      const jsonData = JSON.parse(e.target.result)

      // 验证数据格式
      if (!jsonData.elements || !Array.isArray(jsonData.elements)) {
        ElMessage.error('文件格式不正确，缺少elements数组')
        return
      }

      // 验证版本兼容性
      if (jsonData.version && jsonData.version !== '1.0') {
        ElMessage.warning('文件版本可能不兼容，但仍会尝试导入')
      }

      // 验证元素数据完整性
      const validElements = jsonData.elements.filter(element => {
        // 关系元素可能没有name字段，所以需要特殊处理
        if (element.type === 'relationship') {
          const isValid = element && element.id && element.type && element.sourceId && element.targetId
          if (!isValid) {
            console.warn('Invalid relationship element:', element)
          }
          return isValid
        }
        // 其他元素需要有id、type和name
        const isValid = element && element.id && element.type && element.name
        if (!isValid) {
          console.warn('Invalid element:', element)
        }
        return isValid
      })

      if (validElements.length !== jsonData.elements.length) {
        ElMessage.warning(`发现 ${jsonData.elements.length - validElements.length} 个无效元素，已跳过`)
      }

      // 导入元素数据
      elements.value = validElements

      // 验证关系元素的源和目标是否存在
      const relationships = validElements.filter(el => el.type === 'relationship')
      const nonRelationships = validElements.filter(el => el.type !== 'relationship')
      const validRelationships = relationships.filter(rel => {
        const sourceExists = nonRelationships.some(el => el.id === rel.sourceId)
        const targetExists = nonRelationships.some(el => el.id === rel.targetId)
        if (!sourceExists || !targetExists) {
          console.warn('Relationship references non-existent element:', rel, { sourceExists, targetExists })
          return false
        }
        // 确保关系类型存在，如果没有则设置默认值
        if (!rel.relationshipType) {
          rel.relationshipType = 'association'
          console.log('Set default relationshipType for:', rel.id)
        }
        // 确保其他必要字段存在
        if (!rel.selected) {
          rel.selected = false
        }
        if (!rel.name) {
          rel.name = `${getRelationshipTypeName(rel.relationshipType)}关系`
        }
        return true
      })

      if (validRelationships.length !== relationships.length) {
        ElMessage.warning(`发现 ${relationships.length - validRelationships.length} 个关系引用了不存在的元素，已跳过`)
        // 更新elements，只保留有效的关系
        elements.value = [...nonRelationships, ...validRelationships]
      }

      // 导入画布状态（如果存在）
      if (jsonData.canvasScale !== undefined) {
        canvasScale.value = Math.max(0.1, Math.min(3, jsonData.canvasScale))
      }
      if (jsonData.canvasTranslateX !== undefined) {
        canvasTranslateX.value = jsonData.canvasTranslateX
      }
      if (jsonData.canvasTranslateY !== undefined) {
        canvasTranslateY.value = jsonData.canvasTranslateY
      }

      // 导入图表类型（如果存在）
      if (jsonData.diagramType && ['class', 'activity', 'sequence', 'usecase', 'state'].includes(jsonData.diagramType)) {
        currentDiagramType.value = jsonData.diagramType
      }

      // 重新生成UML图
      generateUML()

      // 显示成功消息
      const elementCount = elements.value.length
      const relationshipCount = elements.value.filter(el => el.type === 'relationship').length
      ElMessage.success(`成功导入 ${elementCount} 个元素（包含 ${relationshipCount} 个关系）`)

      // 重置文件输入
      event.target.value = ''

    } catch (error) {
      console.error('导入文件时出错:', error)
      ElMessage.error('文件格式错误，无法解析JSON数据')
    }
  }

  reader.onerror = () => {
    ElMessage.error('读取文件时出错')
  }

  reader.readAsText(file)
}

const getAvailableModels = (type) => {
  if (!props.useModel || !type) return []
  
  // 只返回有name和description的模型，过滤掉活动图中的活动类型元素
  const availableModels = models.value[type] || []
  return availableModels.filter(model => model.name && model.description && !model.activityType)
}

const confirmModelSelection = () => {
  if (!props.useModel || !selectedModel.value || !pendingElementData.value) return

  const model = models.value[pendingElementData.value.type]?.find(m => m.id === selectedModel.value)
  if (model) {
    // 创建新元素
    const newElement = {
      id: `element_${++elementCounter}`,
      name: `${pendingElementData.value.defaultName || pendingElementData.value.label}${elementCounter}`,
      type: pendingElementData.value.type,
      x: pendingPosition.value.x - 75 - 20, // 考虑padding
      y: pendingPosition.value.y - 50 - 20, // 考虑padding
      attributes: [],
      methods: [],
      modelId: selectedModel.value,
      modelName: model.name,
      activityType: pendingElementData.value.type === 'activity' ? (pendingElementData.value.label === '开始' ? 'start' : pendingElementData.value.label === '结束' ? 'end' : pendingElementData.value.label === '决策' ? 'decision' : 'action') : undefined,
      participantType: pendingElementData.value.type === 'lifeline' ? (pendingElementData.value.label === '参与者' ? 'actor' : 'object') : undefined,
      usecaseType: pendingElementData.value.type === 'usecase' ? (pendingElementData.value.label === '参与者' ? 'actor' : 'usecase') : undefined,
      stateType: pendingElementData.value.type === 'state' ? (pendingElementData.value.label === '初始状态' ? 'initial' : pendingElementData.value.label === '最终状态' ? 'final' : 'state') : undefined
    }

    elements.value.push(newElement)
    generateUML()

    // 重置状态
    showModelSelectionModal.value = false
    const elementType = pendingElementData.value.type
    const elementLabel = pendingElementData.value.label || pendingElementData.value.type
    pendingElementData.value = null
    pendingPosition.value = { x: 0, y: 0 }
    selectedModel.value = ''

    ElMessage.success(`已添加 ${model.name} 类型的 ${elementLabel}`)
  }
 }

const updateElementModel = () => {
  if (!props.useModel || !selectedElement.value || !selectedElement.value.modelId) return

  const model = models.value[selectedElement.value.type]?.find(m => m.id === selectedElement.value.modelId)
  if (model) {
    // 更新元素的模型信息
    selectedElement.value.modelName = model.name

    // 如果模型有预定义的属性和方法，可以在这里添加
    // 这里可以根据需要添加默认的属性和方法

    // 更新UML图
    generateUML()

    ElMessage.success(`已更新为 ${model.name} 模型`)
  }
}


// 查找指定位置的关系线
const findRelationshipAtPosition = (relationship, x, y) => {
  const source = elements.value.find(el => el.id === relationship.sourceId)
  const target = elements.value.find(el => el.id === relationship.targetId)

  if (!source || !target) return null

  const start = getRelationshipStart(relationship)
  const end = getRelationshipEnd(relationship)

  // 计算点到线段的距离
  const distance = pointToLineDistance(x, y, start.x, start.y, end.x, end.y)

  // 如果距离小于阈值（5像素），认为点击了这条线
  if (distance <= 5) {
    return relationship
  }

  return null
}

// 保存图表
const saveDiagram = () => {
  // 检查是否有内容可保存
  if (elements.value.length === 0) {
    ElMessage.warning('画布为空，没有内容可保存')
    return
  }

  // 初始化保存表单
  saveForm.value = {
    id: '',
    title: diagramTitle.value || getDiagramTypeTitle(currentDiagramType.value),
    description: ''
  }

  showSaveDialog.value = true
}

// 删除旧图片
const removeOldImage = async (imageId) => {
  if (!imageId) return true
  
  try {
    const response = await removeImages(imageId)
    if (response && response.code === 200) {
      console.log('旧图片删除成功:', imageId)
      return true
    } else {
      console.warn('删除旧图片失败:', response?.msg)
      return false
    }
  } catch (error) {
    console.error('删除旧图片时出错:', error)
    return false
  }
}

// 确认保存
const confirmSave = async () => {
  if (!saveForm.value.title.trim()) {
    ElMessage.warning('请输入图表标题')
    return
  }

  // 如果是编辑模式，需要ID
  if (saveForm.value.id && saveForm.value.id.trim() === '') {
    ElMessage.warning('编辑模式下请输入图表ID')
    return
  }

  try {
    // 准备保存数据
    const saveData = {
      bizId: props.bizId.toString(), // 使用父组件传递的目录树id
      description: saveForm.value.description || '',
      id: saveForm.value.id || '',
      title: saveForm.value.title.trim(),
      type: currentDiagramType.value, // 添加图表类型
      umlCode: generatePlantUMLCodeLocal(),
      umlJson: JSON.stringify({
        version: '1.0',
        timestamp: new Date().toISOString(),
        diagramType: currentDiagramType.value,
        canvasScale: canvasScale.value,
        canvasTranslateX: canvasTranslateX.value,
        canvasTranslateY: canvasTranslateY.value,
        elements: elements.value,
        metadata: {
          totalElements: elements.value.length,
          relationships: elements.value.filter(el => el.type === 'relationship').length,
          classes: elements.value.filter(el => el.type === 'class').length,
          interfaces: elements.value.filter(el => el.type === 'interface').length,
          activities: elements.value.filter(el => el.type === 'activity').length,
          usecases: elements.value.filter(el => el.type === 'usecase').length,
          states: elements.value.filter(el => el.type === 'state').length,
          lifelines: elements.value.filter(el => el.type === 'lifeline').length
        }
      })
    }
    try {
      const res = await apiSaveDiagram(saveData)
      if (res.code === 200) {
        showSaveDialog.value = false
        ElMessage.success('图表保存成功')
        
        // 保存服务器返回的图片路径
        if (res.msg && res.msg.startsWith('/profile/')) {
          serverImagePath.value = res.msg
        }
        
        // 从图片路径中提取图片ID并存储
        if (res.msg) {
          const imagePathParts = res.msg.split('/')
          const imageFileName = imagePathParts[imagePathParts.length - 1]
          const imageId = imageFileName.split('-')[1]?.split('.')[0] // 提取ID部分
          if (imageId) {
            localStorage.setItem(`image_id_${props.bizId}`, imageId)
            console.log('新图片ID已存储:', imageId)
          }
        }
        
        // 发射保存成功事件，包含服务器返回的图片路径
        emit('save-success', { ...saveData, serverImagePath: res.msg })
      } else if (res.code === 500) {
        showSaveDialog.value = false
        ElMessage.error(res.msg)
      }
    } catch (err) {
      showSaveDialog.value = false
      ElMessage.error('图表保存失败')
    }

    // 清空表单
    saveForm.value = {
      id: '',
      title: '',
      description: ''
    }

  } catch (error) {
    console.error('保存图表时出错:', error)
    ElMessage.error('保存失败，请重试')
  }
}

// 获取UML图片（供父组件调用）
const getUmlImage = () => {
  // 优先返回服务器图片路径，如果没有则返回预览图片URL
  if (serverImagePath.value) {
    return serverImagePath.value
  }
  return umlImageUrl.value
}

// 加载UML数据（供父组件调用）
const loadUmlData = (umlData) => {
  try {
    if (!umlData) return false
    
    // 如果传入的是字符串，尝试解析为对象
    const data = typeof umlData === 'string' ? JSON.parse(umlData) : umlData
    
    // 设置图表类型
    if (data.diagramType && ['class', 'activity', 'sequence', 'usecase', 'state'].includes(data.diagramType)) {
      currentDiagramType.value = data.diagramType
    }
    
    // 设置画布变换
    if (data.canvasScale !== undefined) {
      canvasScale.value = Math.max(0.1, Math.min(3, data.canvasScale))
    }
    if (data.canvasTranslateX !== undefined) {
      canvasTranslateX.value = data.canvasTranslateX
    }
    if (data.canvasTranslateY !== undefined) {
      canvasTranslateY.value = data.canvasTranslateY
    }
    
    // 设置元素
    if (Array.isArray(data.elements)) {
      elements.value = JSON.parse(JSON.stringify(data.elements))
      
      // 更新元素计数器，避免ID冲突
      const maxId = Math.max(...elements.value.map(el => {
        const idMatch = el.id.match(/\d+$/)
        return idMatch ? parseInt(idMatch[0]) : 0
      }), 0)
      elementCounter = maxId + 1
    }
    
    // 重绘画布并生成UML
    nextTick(() => {
      redrawCanvas()
      generateUML()
    })
    
    return true
  } catch (error) {
    console.error('加载UML数据失败:', error)
    return false
  }
}

// 暴露方法给父组件
defineExpose({
  getUmlImage,
  generatePlantUMLCode: generatePlantUMLCodeLocal,
  saveDiagram,
  loadUmlData
})
</script>

<style scoped lang="scss">
@use './index.scss' as *;

.form-tip {
  margin-top: 4px;
  color: #666;
  line-height: 1.4;
}
</style>
